﻿import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import './staff.css'
import * as actions from './actions'
import { parseStaff, uploadStaff } from '../svc/service-broker'
import XLSX from 'xlsx'

const DATA_WIDTH = 7; 

export default class extends Component {
    static propTypes = {
        filename: PropTypes.string,
        isParsing: PropTypes.bool,
        // organization tree, constructed by server
        // it's also the flag that file has been validated successfully.
        org: PropTypes.object,
    }
    constructor() {
        this.fileInp = React.createRef();
    }
    openDialog = () => this.fileInp.current.click();
    fileSelected = async e => {
        let { dispatch } = this.props,
            file = e.target.files[0];
        dispatch(actions.setFilename(file && file.name || ''));
        if (file) {
            dispatch(actions.setParsingState(true));

            // read excel data as 
            let arr = await readFile(file);
            let deps = buildDepTree(arr);
            convertLevel(arr);
            let root = attachEmp2Org(deps, arr);

            dispatch(actions.setOrgGraph(root));
            dispatch(actions.setParsingState(false));
        } else {
            dispatch(actions.setOrgGraph(null));
        }


        function readFile(file) {
            return new Promise(res => {
                let fr = new FileReader();
                fr.onload = e => {
                    let workbook = XLSX.read(e.target.result, { type: 'binary' });
                    let arr = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], { header: 1 });
                    arr = arr.slice(2);     // remove top 2 rows
                    arr.forEach(row => {    // remove all empty chars(i.e. space)
                        for (var i = 0; i < DATA_WIDTH; i++)
                            if (row[i]) {
                                row[i] = row[i].toString().replace(/\s/, '');
                                if (!row[i]) row[i] = null; // convert '' to null
                            }
                    })
                    res(arr);
                }
                fr.readAsBinaryString(file);
            })
        }
        function buildDepTree(arr) {
            let deps = [], curDep = null, curSec = null;
            arr.forEach(row => {
                if (arr[0] && arr[0] !== (curDep && curDep.name)) { // department changed
                    curDep = { name: arr[0], secs: [], teachers: [] };
                    curSec = null;
                    deps.push(curDep);
                }
                if (arr[1] && arr[1] !== (curSec && curSec.name)) { // section changed
                    curSec = new { name: arr[1], teachers:[] };
                    curDep.secs.push(curSec);
                }
                row[0] = curDep;
                row[1] = curSec;
                if (row[6] === '信息中心') curDep.isInfoCenter = true;
            })
            return deps;
        }
        function convertLevel(arr) {
            let curDep = null, depRising = false,
                curSec = null, secRising = false;
            arr.forEach(row => {
                // check department and section changing
                depRising = row[0] && row[0] !== curDep;
                curDep = row[0];
                secRising = row[1] && row[1] !== curSec;
                curSec = row[1];

                // conver level
                let level = 0;
                switch (row[5]) {
                    case '校领导': level = 16; break;
                    case '处级': level = depRising ? 8 : 4; break;
                    case '科级': level = secRising ? 2 : 1; break;
                    case '普通':
                    default: level = 0; break;
                }
                row[5] = level;
            })
        }
        function attachEmp2Org(deps, arr) {
            let root = { teachers: [], deps: [] };
            let emp = { eno: row[2], name: row[3], level: row[6] };
            arr.forEach(row => {
                // section directors and normal employees
                if (row[1]) row[1].teachers.push(emp);

                // departments leaders
                else if (row[0]) row[0].teachers.push(emp);

                // presidents
                else root.teachers.push(emp);
            })
            deps.forEach(dep => root.deps.push(dep));
            return root;
        }
    };
    upload = async () => {
        await uploadStaff(this.props.org);
    }
    render() {
        return (
            <div>
                <h1 className="staff-title">组织结构维护</h1>
                <div>
                    <div className="staff-header">
                        <label>组织机构文件(.xlsx)：</label>
                        <div>
                            <button onClick={this.openDialog}>选择文件</button>
                            <button disabled={!this.props.org} onClick={this.upload}>上传</button>
                        </div>
                    </div>
                    <div className="staff-file">{this.props.filename || ''}</div>
                    <input type="file" accept=".xlsx" ref={this.fileInp} style={{ display: none }}
                        onChange={this.fileSelected}/>
                </div>
                <div>
                    {this.props.isParsing === true &&
                        <div className="staff-parsing">正在分析Excel文件，请稍候……</div>}
                    {this.props.isParsing === false &&
                        
                    }
                </div>
            </div>
        )
    }
}